using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using JGSY.CMS.LowCode.Platform.Application.Interfaces;
using JGSY.CMS.LowCode.Platform.Domain.Entities;

namespace JGSY.CMS.LowCode.Platform.Controllers
{
    /// <summary>
    /// 审计日志API控制器
    /// </summary>
    [ApiController]
    [Route("api/audit")]
    [Authorize]
    public class AuditController : ControllerBase
    {
        private readonly IAuditService _auditService;
        private readonly ILogger<AuditController> _logger;

        public AuditController(IAuditService auditService, ILogger<AuditController> logger)
        {
            _auditService = auditService;
            _logger = logger;
        }

        /// <summary>
        /// 记录审计日志
        /// </summary>
        [HttpPost("log")]
        public async Task<IActionResult> LogAudit([FromBody] AuditLogEntry request)
        {
            try
            {
                await _auditService.LogAsync(request);
                return Ok(new { message = "审计日志记录成功" });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "记录审计日志失败");
                return StatusCode(500, new { message = "记录审计日志失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 批量记录审计日志
        /// </summary>
        [HttpPost("log-batch")]
        public async Task<IActionResult> LogBatchAudit([FromBody] List<AuditLogEntry> requests)
        {
            try
            {
                await _auditService.LogBatchAsync(requests);
                return Ok(new { message = $"批量记录 {requests.Count} 条审计日志成功" });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "批量记录审计日志失败");
                return StatusCode(500, new { message = "批量记录审计日志失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 查询审计日志
        /// </summary>
        [HttpGet("logs")]
        public async Task<IActionResult> GetLogs([FromQuery] string tenantId, [FromQuery] AuditLogFilter filter)
        {
            try
            {
                var result = await _auditService.GetLogsAsync(tenantId, filter);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "查询审计日志失败");
                return StatusCode(500, new { message = "查询审计日志失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 获取单条审计日志
        /// </summary>
        [HttpGet("logs/{logId}")]
        public async Task<IActionResult> GetLog(Guid logId)
        {
            try
            {
                var log = await _auditService.GetLogAsync(logId);
                if (log == null)
                {
                    return NotFound(new { message = "审计日志不存在" });
                }
                return Ok(log);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取审计日志失败");
                return StatusCode(500, new { message = "获取审计日志失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 获取用户审计日志
        /// </summary>
        [HttpGet("users/{userId}/logs")]
        public async Task<IActionResult> GetUserLogs(string tenantId, string userId, 
            [FromQuery] DateTime? startDate = null, [FromQuery] DateTime? endDate = null)
        {
            try
            {
                var logs = await _auditService.GetUserLogsAsync(tenantId, userId, startDate, endDate);
                return Ok(logs);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取用户审计日志失败");
                return StatusCode(500, new { message = "获取用户审计日志失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 获取资源审计日志
        /// </summary>
        [HttpGet("resources/{resourceType}/{resourceId}/logs")]
        public async Task<IActionResult> GetResourceLogs(string tenantId, string resourceType, string resourceId,
            [FromQuery] DateTime? startDate = null, [FromQuery] DateTime? endDate = null)
        {
            try
            {
                var logs = await _auditService.GetResourceLogsAsync(tenantId, resourceType, resourceId, startDate, endDate);
                return Ok(logs);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取资源审计日志失败");
                return StatusCode(500, new { message = "获取资源审计日志失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 获取审计统计
        /// </summary>
        [HttpGet("statistics")]
        public async Task<IActionResult> GetStatistics([FromQuery] string tenantId,
            [FromQuery] DateTime? startDate = null, [FromQuery] DateTime? endDate = null)
        {
            try
            {
                var statistics = await _auditService.GetStatisticsAsync(tenantId, startDate, endDate);
                return Ok(statistics);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取审计统计失败");
                return StatusCode(500, new { message = "获取审计统计失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 获取活动汇总
        /// </summary>
        [HttpGet("activity-summary")]
        public async Task<IActionResult> GetActivitySummary([FromQuery] string tenantId, 
            [FromQuery] DateTime date, [FromQuery] string groupBy = "hour")
        {
            try
            {
                var summary = await _auditService.GetActivitySummaryAsync(tenantId, date, groupBy);
                return Ok(summary);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取活动汇总失败");
                return StatusCode(500, new { message = "获取活动汇总失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 获取用户活动排行
        /// </summary>
        [HttpGet("top-users")]
        public async Task<IActionResult> GetTopUsers([FromQuery] string tenantId,
            [FromQuery] DateTime? startDate = null, [FromQuery] DateTime? endDate = null, 
            [FromQuery] int count = 10)
        {
            try
            {
                var topUsers = await _auditService.GetTopUsersAsync(tenantId, startDate, endDate, count);
                return Ok(topUsers);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取用户活动排行失败");
                return StatusCode(500, new { message = "获取用户活动排行失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 获取风险操作
        /// </summary>
        [HttpGet("risk-operations")]
        public async Task<IActionResult> GetRiskOperations([FromQuery] string tenantId,
            [FromQuery] string riskLevel = "High", [FromQuery] DateTime? startDate = null, 
            [FromQuery] DateTime? endDate = null)
        {
            try
            {
                var riskOps = await _auditService.GetRiskOperationsAsync(tenantId, riskLevel, startDate, endDate);
                return Ok(riskOps);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取风险操作失败");
                return StatusCode(500, new { message = "获取风险操作失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 创建审计规则
        /// </summary>
        [HttpPost("rules")]
        public async Task<IActionResult> CreateRule([FromBody] AuditRule rule)
        {
            try
            {
                var createdRule = await _auditService.CreateRuleAsync(rule);
                return Ok(createdRule);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "创建审计规则失败");
                return StatusCode(500, new { message = "创建审计规则失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 更新审计规则
        /// </summary>
        [HttpPut("rules/{ruleId}")]
        public async Task<IActionResult> UpdateRule(Guid ruleId, [FromBody] AuditRule rule)
        {
            try
            {
                rule.Id = ruleId;
                var updatedRule = await _auditService.UpdateRuleAsync(rule);
                return Ok(updatedRule);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "更新审计规则失败");
                return StatusCode(500, new { message = "更新审计规则失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 删除审计规则
        /// </summary>
        [HttpDelete("rules/{ruleId}")]
        public async Task<IActionResult> DeleteRule(Guid ruleId)
        {
            try
            {
                await _auditService.DeleteRuleAsync(ruleId);
                return Ok(new { message = "审计规则删除成功" });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "删除审计规则失败");
                return StatusCode(500, new { message = "删除审计规则失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 获取审计规则列表
        /// </summary>
        [HttpGet("rules")]
        public async Task<IActionResult> GetRules([FromQuery] string tenantId)
        {
            try
            {
                var rules = await _auditService.GetRulesAsync(tenantId);
                return Ok(rules);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取审计规则失败");
                return StatusCode(500, new { message = "获取审计规则失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 启用/禁用审计规则
        /// </summary>
        [HttpPatch("rules/{ruleId}/toggle")]
        public async Task<IActionResult> ToggleRule(Guid ruleId, [FromBody] bool enabled)
        {
            try
            {
                var success = await _auditService.ToggleRuleAsync(ruleId, enabled);
                if (success)
                {
                    return Ok(new { message = "审计规则状态更新成功" });
                }
                return NotFound(new { message = "审计规则不存在" });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "更新审计规则状态失败");
                return StatusCode(500, new { message = "更新审计规则状态失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 获取审计配置
        /// </summary>
        [HttpGet("configuration")]
        public async Task<IActionResult> GetConfiguration([FromQuery] string tenantId)
        {
            try
            {
                var configuration = await _auditService.GetConfigurationAsync(tenantId);
                return Ok(configuration);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取审计配置失败");
                return StatusCode(500, new { message = "获取审计配置失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 更新审计配置
        /// </summary>
        [HttpPut("configuration")]
        public async Task<IActionResult> UpdateConfiguration([FromBody] AuditConfiguration configuration)
        {
            try
            {
                var updatedConfig = await _auditService.UpdateConfigurationAsync(configuration);
                return Ok(updatedConfig);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "更新审计配置失败");
                return StatusCode(500, new { message = "更新审计配置失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 创建审计报告
        /// </summary>
        [HttpPost("reports")]
        public async Task<IActionResult> CreateReport([FromBody] AuditReportRequest request)
        {
            try
            {
                var tenantId = User.FindFirst("TenantId")?.Value ?? "default";
                var report = await _auditService.CreateReportAsync(tenantId, request);
                return Ok(report);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "创建审计报告失败");
                return StatusCode(500, new { message = "创建审计报告失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 获取审计报告列表
        /// </summary>
        [HttpGet("reports")]
        public async Task<IActionResult> GetReports([FromQuery] string tenantId)
        {
            try
            {
                var reports = await _auditService.GetReportsAsync(tenantId);
                return Ok(reports);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取审计报告失败");
                return StatusCode(500, new { message = "获取审计报告失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 下载审计报告
        /// </summary>
        [HttpGet("reports/{reportId}/download")]
        public async Task<IActionResult> DownloadReport(Guid reportId)
        {
            try
            {
                var report = await _auditService.GetReportAsync(reportId);
                if (report == null)
                {
                    return NotFound(new { message = "审计报告不存在" });
                }

                var fileBytes = await _auditService.DownloadReportAsync(reportId);
                return File(fileBytes, "application/octet-stream", $"{report.Name}.{report.Format.ToLower()}");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "下载审计报告失败");
                return StatusCode(500, new { message = "下载审计报告失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 清理过期日志
        /// </summary>
        [HttpPost("cleanup/expired")]
        public async Task<IActionResult> CleanupExpiredLogs([FromQuery] string tenantId)
        {
            try
            {
                var deletedCount = await _auditService.CleanupExpiredLogsAsync(tenantId);
                return Ok(new { message = $"清理了 {deletedCount} 条过期日志" });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "清理过期日志失败");
                return StatusCode(500, new { message = "清理过期日志失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 导出审计日志
        /// </summary>
        [HttpPost("export")]
        public async Task<IActionResult> ExportLogs([FromBody] ExportRequest request)
        {
            try
            {
                var fileBytes = await _auditService.ExportLogsAsync(request.TenantId, request.Filter, request.Format);
                var fileName = $"audit_logs_{DateTime.Now:yyyyMMdd}.{request.Format}";
                return File(fileBytes, "application/octet-stream", fileName);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "导出审计日志失败");
                return StatusCode(500, new { message = "导出审计日志失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 合规性检查
        /// </summary>
        [HttpPost("compliance/check")]
        public async Task<IActionResult> CheckCompliance([FromBody] ComplianceCheckRequest request)
        {
            try
            {
                var report = await _auditService.CheckComplianceAsync(request.TenantId, request.Standard, 
                    request.StartDate, request.EndDate);
                return Ok(report);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "合规性检查失败");
                return StatusCode(500, new { message = "合规性检查失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 获取实时告警
        /// </summary>
        [HttpGet("alerts/real-time")]
        public async Task<IActionResult> GetRealTimeAlerts([FromQuery] string tenantId)
        {
            try
            {
                var alerts = await _auditService.GetRealTimeAlertsAsync(tenantId);
                return Ok(alerts);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取实时告警失败");
                return StatusCode(500, new { message = "获取实时告警失败", error = ex.Message });
            }
        }
    }

    // 请求DTO类
    public class ExportRequest
    {
        public string TenantId { get; set; } = string.Empty;
        public AuditLogFilter Filter { get; set; } = new();
        public string Format { get; set; } = "xlsx";
    }

    public class ComplianceCheckRequest
    {
        public string TenantId { get; set; } = string.Empty;
        public string Standard { get; set; } = string.Empty;
        public DateTime? StartDate { get; set; }
        public DateTime? EndDate { get; set; }
    }
}
